/**
  Copyright (c) [2024] [JiangNan]
  [simple-go-test] is licensed under Mulan PSL v2.
  You can use this software according to the terms and conditions of the Mulan PSL v2.
  You may obtain a copy of Mulan PSL v2 at:
           http://license.coscl.org.cn/MulanPSL2
  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
  See the Mulan PSL v2 for more details.
*/

package control

import (
	"fmt"
	"log"
	"vector/tools"

	"gitee.com/jn-qq/go-tools/progressbar"
)

type VectorFlow struct{}

// ProductFunc 生产者 - 读取表格测试集
func (vf *VectorFlow) ProductFunc() ([]any, <-chan any) {
	reader, err := tools.NewExcelReader(tools.Config.DataSource, tools.Config.Sheet)
	if err != nil {
		log.Fatalf("读取数据集失败,文件：%s，表：%s\n%#v", tools.Config.DataSource, tools.Config.Sheet, err)
		return nil, nil
	}
	defer reader.Close()

	// 初始化进度条
	if tools.Config.IsSimplePrint {
		tools.Bar = progressbar.NewBar("Running", reader.RowNum-1, ">")
	}

	var inChan = make(chan any)
	var result []any

	if reader.RowNum >= 10000 {
		// 流式读取
		rows, err := reader.StreamReadSheet()
		if err != nil {
			log.Fatalf("读取表失败：%s\n%#v", tools.Config.Sheet, err)
		}
		go func() {
			defer close(inChan)
			for row := range rows {
				inChan <- row
			}
		}()
	} else {
		close(inChan)
		inChan = nil
		// 批量读取
		rows, err := reader.ReadSheet()
		if err != nil {
			log.Fatalf("读取表失败：%s\n%#v", tools.Config.Sheet, err)
		}
		for _, row := range rows {
			result = append(result, row)
		}
	}

	return result, inChan
}

// HandleFunc 执行者 - 处理具体逻辑
func (vf *VectorFlow) HandleFunc(item any) any {
	result := item.(map[string]any)

	task := TaskPool.Get().(Task)
	defer TaskPool.Put(task)
	defer task.Reset()
	if err := task.NewTaskData(result); err != nil {
		result["备注"] = err.Error()
		return result
	} else {
		task.Do()
		return task.Result()
	}

	//if taskFunction, ok := TaskMaps[tools.Config.RunMode]; ok {
	//	task := taskFunction()
	//	err := task.NewTaskData(result)
	//	if err != nil {
	//		result["备注"] = err.Error()
	//		return result
	//	}
	//
	//	task.Do()
	//	return task.Result()
	//} else {
	//	result["备注"] = "暂不支持该模式"
	//	return result
	//}
}

// ConsumerFunc 消费者 - 将处理结果写入表格
func (vf *VectorFlow) ConsumerFunc(index int, item any) {
	// 获取表头缓存，避免重复调用
	headers := tools.Config.Excel.GetExcelHeader()

	// 安全类型断言
	resultMap, ok := item.(map[string]any)
	if !ok {
		log.Printf("ConsumerFunc: item 类型错误，期望 map[string]any")
		return
	}

	if !tools.Config.IsSimplePrint {
		fmt.Println("已完成：", index, " 行")
	} else {
		tools.Bar.PrintProgress(index + 1)
	}

	if child, ok := resultMap["child"]; ok {
		childSlice, ok := child.([]map[string]any)
		if !ok {
			log.Printf("ConsumerFunc: child 类型错误，期望 []map[string]any")
			return
		}

		for i, childItem := range childSlice {

			//tools.MapCopy(resultMap, childItem)
			row := make([]any, 0, len(headers))
			for _, name := range headers {
				if value, ok1 := childItem[name]; ok1 {
					row = append(row, value)
				} else {
					row = append(row, resultMap[name])
				}
			}

			// 流式写入并检查错误
			if err := tools.EF.SetRow(index+tools.AddRow+i, row); err != nil {
				log.Printf("写入行失败: %v", err)
			}
		}
		tools.AddRow += len(childSlice) - 1
	} else {
		row := make([]any, 0, len(headers))
		for _, name := range headers {
			row = append(row, resultMap[name])
		}

		if err := tools.EF.SetRow(index+tools.AddRow, row); err != nil {
			log.Printf("写入行失败: %v", err)
		}
	}
}
